package com.xpq.ddns;

import com.aliyun.alidns20150109.Client;
import com.aliyun.alidns20150109.models.*;
import com.aliyun.tea.TeaException;
import com.aliyun.tea.TeaModel;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.Common;
import lombok.extern.slf4j.Slf4j;

/**
 * 域名解析器
 */
@Slf4j
public class DDNS {
    /**
     * Initialization  初始化公共请求参数
     */
    private Client Initialization(String regionId, String accessKeyId, String accessKeySecret){
        Config config = new Config();
        // 您的AccessKey ID
        config.accessKeyId = accessKeyId;
        // 您的AccessKey Secret
        config.accessKeySecret = accessKeySecret;

        // 您的可用区ID
        config.regionId = regionId;
        log.info("开始建立连接......");
        try {
            return new Client(config);
        } catch (Exception e) {
            log.error("建立连接失败！");
            throw new RuntimeException("建立连接失败！");
        }
    }

    /**
     * 获取主域名的所有解析记录列表
     */
    private DescribeDomainRecordsResponse DescribeDomainRecords(Client client, String domainName, String RR, String recordType){
        DescribeDomainRecordsRequest req = new DescribeDomainRecordsRequest();
        // 主域名
        req.domainName = domainName;
        // 主机记录
        req.RRKeyWord = RR;
        // 解析记录类型
        req.type = recordType;
        try {
            DescribeDomainRecordsResponse resp = client.describeDomainRecords(req);
            log.info("-------------------获取主域名的所有解析记录列表--------------------");
            log.info(Common.toJSONString(TeaModel.buildMap(resp)));
            return resp;
        } catch (TeaException error) {
            log.error(error.message);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            log.error(error.message);
        }
        return null;
    }

    /**
     * 修改解析记录
     */
    private void UpdateDomainRecord(Client client, UpdateDomainRecordRequest req){
        try {
            UpdateDomainRecordResponse resp = client.updateDomainRecord(req);
            log.info("-------------------修改解析记录--------------------");
            log.info(Common.toJSONString(TeaModel.buildMap(resp)));
        } catch (TeaException error) {
            log.error(error.message);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            log.error(error.message);
        }
    }

    /**
     * 更新域名解析
     * @param info
     */
    public void update(Info info) {
        // 获取连接客户端
        Client client = Initialization(info.getRegionId(), info.getAccessKeyId(), info.getAccessKeySecret());
        // 获取云服务器解析记录
        DescribeDomainRecordsResponse resp = DescribeDomainRecords(
                client, info.getDomainName(),
                info.getRR(),
                info.getRecordType()
        );
        // 判断解析记录是否为空，如果为空，则方法结束
        if (
                com.aliyun.teautil.Common.isUnset(TeaModel.buildMap(resp))
                || com.aliyun.teautil.Common.isUnset(TeaModel.buildMap(resp.body.domainRecords.record.get(0)))
        ) {
            log.error("错误参数！获取到的解析记录为空！");
            return ;
        }
        // 获取到第一个解析记录
        DescribeDomainRecordsResponseBody.DescribeDomainRecordsResponseBodyDomainRecordsRecord record =
                resp.body.domainRecords.record.get(0);
        // 记录ID
        String recordId = record.recordId;
        // 记录值
        String recordsValue = record.value;
        log.info("-------------------原本域名对应IP为：{}-------------------------", recordsValue);
        log.info("-------------------当前主机公网IP为：{}-------------------------", info.getCurrentHostIP());
        if (Common.equalString(info.getCurrentHostIP(), recordsValue)) {
            log.info("本机ip没有发生变化");
            return;
        }
        // 修改解析记录
        UpdateDomainRecordRequest req = new UpdateDomainRecordRequest();
        // 主机记录
        req.RR = info.getRR();
        // 记录ID
        req.recordId = recordId;
        // 将主机记录值改为当前主机IP
        req.value = info.getCurrentHostIP();
        // 解析记录类型
        req.type = info.getRecordType();
        UpdateDomainRecord(client, req);
        log.info("域名解析修改成功！");
    }

    /**
     * 修改域名解析所需要的配置信息
     */
    static class Info{
        private String accessKeyId;
        private String accessKeySecret;
        private String regionId;
        private String domainName;
        private String RR;
        private String recordType;
        private String currentHostIP;

        public Info() {
        }

        public Info(
                String accessKeyId,
                String accessKeySecret,
                String regionId,
                String domainName,
                String RR,
                String recordType,
                String currentHostIP
        ) {
            this.accessKeyId = accessKeyId;
            this.accessKeySecret = accessKeySecret;
            this.regionId = regionId;
            this.domainName = domainName;
            this.RR = RR;
            this.recordType = recordType;
            this.currentHostIP = currentHostIP;
        }

        public String getAccessKeyId() {
            return accessKeyId;
        }

        public void setAccessKeyId(String accessKeyId) {
            this.accessKeyId = accessKeyId;
        }

        public String getAccessKeySecret() {
            return accessKeySecret;
        }

        public void setAccessKeySecret(String accessKeySecret) {
            this.accessKeySecret = accessKeySecret;
        }

        public String getRegionId() {
            return regionId;
        }

        public void setRegionId(String regionId) {
            this.regionId = regionId;
        }

        public String getDomainName() {
            return domainName;
        }

        public void setDomainName(String domainName) {
            this.domainName = domainName;
        }

        public String getRR() {
            return RR;
        }

        public void setRR(String RR) {
            this.RR = RR;
        }

        public String getRecordType() {
            return recordType;
        }

        public void setRecordType(String recordType) {
            this.recordType = recordType;
        }

        public String getCurrentHostIP() {
            return currentHostIP;
        }

        public void setCurrentHostIP(String currentHostIP) {
            this.currentHostIP = currentHostIP;
        }

        @Override
        public String toString() {
            return "Info{" +
                    "accessKeyId='" + accessKeyId + '\'' +
                    ", accessKeySecret='" + accessKeySecret + '\'' +
                    ", regionId='" + regionId + '\'' +
                    ", domainName='" + domainName + '\'' +
                    ", RR='" + RR + '\'' +
                    ", recordType='" + recordType + '\'' +
                    ", currentHostIP='" + currentHostIP + '\'' +
                    '}';
        }
    }



}
